package com.hentica.app.component.photo;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.RequiresApi;
import android.support.v4.app.Fragment;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.widget.Toast;

import com.hentica.imagecompress.CompressListener;
import com.hentica.imagecompress.CompressUtil;
import com.hentica.imagecompress.Option;
import com.soundcloud.android.crop.Crop;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static android.app.Activity.RESULT_OK;

/**
 * Created by pxy on 2018/2/25.
 */

public class TakePhotoCamera implements TakePhoto {
    private List<String> photos;
    private TakePhotoCallBack takePhotoCallBack;
    private Activity activity;
    private CropOption option = new CropOption();
    private boolean isCrop = true;
    private Option mComprossOption = new Option();
    private boolean isCompross = false;
    private File cropImageFile;
    private File tempPhotoFile;
    Fragment fragment;
    private static final int REQUEST_CAMERA = 5;
    private static final int IMAGE_CROP_CODE = 1;
    private static final int CAMERA_REQUEST_CODE = 2;

    public TakePhotoCamera(Activity activity, boolean isCrop, TakePhotoCallBack takePhotoCallBack) {
        this.activity = activity;
        this.isCrop = isCrop;
        this.takePhotoCallBack = takePhotoCallBack;
        this.photos = new ArrayList();
    }

    public TakePhotoCamera(Activity activity, boolean isCrop, CropOption option, boolean isCompross, Option mComprossOption, TakePhotoCallBack takePhotoCallBack) {
        this.activity = activity;
        this.isCrop = isCrop;
        this.option = option;
        this.isCompross = isCompross;
        this.mComprossOption = mComprossOption;
        this.takePhotoCallBack = takePhotoCallBack;
        this.photos = new ArrayList();
    }

    public TakePhotoCamera(Fragment fragment, Activity activity, boolean isCrop, CropOption option, boolean isCompross, Option mComprossOption, TakePhotoCallBack takePhotoCallBack) {
        this.activity = activity;
        this.isCrop = isCrop;
        this.option = option;
        this.isCompross = isCompross;
        this.fragment = fragment;
        this.mComprossOption = mComprossOption;
        this.takePhotoCallBack = takePhotoCallBack;
        this.photos = new ArrayList();
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void camera() {
        if (this.activity != null) {
            Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE");
            if (cameraIntent.resolveActivity(this.activity.getPackageManager()) != null) {
                this.tempPhotoFile = new File(FileUtils.createRootPath(this.activity) + "/" + System.currentTimeMillis() + ".jpg");
                FileUtils.createFile(this.tempPhotoFile);
                Uri uri = FileProvider.getUriForFile(this.activity, FileUtils.getApplicationId(this.activity) + ".provider", this.tempPhotoFile);
                List<ResolveInfo> resInfoList = this.activity.getPackageManager().queryIntentActivities(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY);
                Iterator iterator = resInfoList.iterator();

                while(iterator.hasNext()) {
                    ResolveInfo resolveInfo = (ResolveInfo)iterator.next();
                    String packageName = resolveInfo.activityInfo.packageName;
                    this.activity.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }

                cameraIntent.putExtra("output", uri);
                if (this.fragment != null) {
                    this.fragment.startActivityForResult(cameraIntent, REQUEST_CAMERA);
                } else {
                    this.activity.startActivityForResult(cameraIntent, REQUEST_CAMERA);
                }
            } else {
                Toast.makeText(this.activity, "出错", Toast.LENGTH_SHORT).show();
            }
        }

    }

    private void crop(String imagePath) {
        if (this.activity != null) {
            this.cropImageFile = new File(FileUtils.createRootPath(this.activity) + "/" + System.currentTimeMillis() + ".jpg");
            Uri destination = Uri.fromFile(this.cropImageFile);
            Uri source = Uri.fromFile(new File(imagePath));
            Crop.of(source, destination).withMaxSize(this.option.maxSizeX, this.option.maxSizeY).withAspect(this.option.aspectX, this.option.aspectY).start(this.activity, this.fragment);
        }

    }

    private Uri getImageContentUri(File imageFile) {
        if (this.activity != null) {
            String filePath = imageFile.getAbsolutePath();
            Cursor cursor = this.activity.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{"_id"}, "_data=? ", new String[]{filePath}, (String)null);
            if (cursor != null && cursor.moveToFirst()) {
                int id = cursor.getInt(cursor.getColumnIndex("_id"));
                Uri baseUri = Uri.parse("content://media/external/images/media");
                cursor.close();
                return Uri.withAppendedPath(baseUri, "" + id);
            } else if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put("_data", filePath);
                if (cursor != null) {
                    cursor.close();
                }

                return this.activity.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    private String beforeCurrentPath = "";

    public void handleActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == IMAGE_CROP_CODE && resultCode == RESULT_OK) {
            if (this.cropImageFile != null) {
                this.complete(this.cropImageFile.getAbsolutePath());
            } else {
                this.error();
            }
        } else if (requestCode == REQUEST_CAMERA) {
            if (resultCode == RESULT_OK) {
                if (this.tempPhotoFile != null) {
                    beforeCurrentPath = tempPhotoFile.getAbsolutePath();
                    if (this.isCrop) {
                        this.crop(this.tempPhotoFile.getAbsolutePath());
                    } else {
                        this.complete(this.tempPhotoFile.getAbsolutePath());
                    }
                } else {
                    this.error();
                }
            } else if (this.tempPhotoFile != null && this.tempPhotoFile.exists()) {
                this.tempPhotoFile.delete();
            }
        } else if(!TextUtils.isEmpty(beforeCurrentPath)){
            complete(beforeCurrentPath);
        }
        else {
            this.error();
        }

    }

    @RequiresApi(
            api = Build.VERSION_CODES.M
    )
    public void takePhoto() {
        this.camera();
    }

    public void detch() {
        this.activity = null;
    }

    private void complete(String path) {
        this.photos.clear();
        this.photos.add(path);
        if (this.takePhotoCallBack != null) {
            if (this.isCompross) {
                CompressUtil.compressBitmaps(this.photos, this.mComprossOption, new CompressListener() {
                    public void result(List<String> filePaths) {
                        TakePhotoCamera.this.takePhotoCallBack.getPhotos(filePaths);
                    }
                });
            } else {
                this.takePhotoCallBack.getPhotos(this.photos);
            }
        }

    }

    private void error() {
        if (this.takePhotoCallBack != null) {
            this.takePhotoCallBack.error();
        }

    }
}
